home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / search3d.pro < prev    next >
Text File  |  1997-07-08  |  8KB  |  193 lines

  1. ; $Id: search3d.pro,v 1.7 1997/01/15 03:11:50 ali Exp $
  2.  
  3. ; Copyright (c) 1992-1997, Research Systems, Inc. All rights reserved.
  4. ;    Unauthorized reproduction prohibited.
  5. ;
  6. ;+
  7. ; NAME:
  8. ;    SEARCH3D
  9. ;
  10. ; PURPOSE:
  11. ;    This function finds "objects" or regions of similar data
  12. ;       values within a 3-D array of data. Given a starting location
  13. ;       and a range of values to search for, SEARCH3D will find all
  14. ;       the cells within the array that are within the specified range
  15. ;       of values, and have some path of connectivity through these cells
  16. ;       to the starting location. See the procedure "SEARCH2D" for the
  17. ;       two dimensional case.
  18. ;
  19. ;       This function returns a list of the array subscripts that define
  20. ;       the selected object or region.
  21. ;
  22. ; CATEGORY:
  23. ;       Data subsetting.
  24. ;    Image manipulation.
  25. ;
  26. ; CALLING SEQUENCE:
  27. ;       Region = SEARCH3D(Array, Xpos, Ypos, Zpos, Min_val, Max_val)
  28. ;
  29. ; INPUTS:
  30. ;       Array:      The 3-D array of data to search.
  31. ;                   Data type : Any 3-D array except string or structure.
  32. ;       Xpos:       The X coordinate(s) (first subscript into the 3-D Array)
  33. ;                   of the seed point(s) for the search.   Xpos can be a
  34. ;                   single value, or an array of subscripts specifying the
  35. ;                   X coordinates of a seed region.   Xpos must have the same
  36. ;                   number of elements as Ypos and Zpos.
  37. ;                   Data type : Long or Lonarr.
  38. ;       Ypos:       The Y coordinate(s) (second subscript into the 3-D Array)
  39. ;                   of the seed point(s) for the search.   Ypos can be a
  40. ;                   single value, or an array of subscripts specifying the
  41. ;                   Y coordinates of a seed region.   Ypos must have the same
  42. ;                   number of elements as Xpos and Zpos.
  43. ;                   Data type : Long or Lonarr.
  44. ;       Zpos:       The Z coordinate(s) (third subscript into the 3-D Array)
  45. ;                   of the seed point(s) for the search.   Zpos can be a
  46. ;                   single value, or an array of subscripts specifying the
  47. ;                   Z coordinates of a seed region.   Zpos must have the same
  48. ;                   number of elements as Xpos and Ypos.
  49. ;                   Data type : Long or Lonarr.
  50. ;       Min_val:    The minimum data value to search for. All cells that
  51. ;                   are connected to the starting cell, and have a value
  52. ;                   greater than or equal to Min_val and less than or equal
  53. ;                   to Max_val, will be considered part of the "object".
  54. ;                   If omitted, the default is MIN(Array[Xpos, Ypos, Zpos]) .
  55. ;       Max_val:    The maximum data value to search for.
  56. ;                   If omitted, the default is MAX(Array[Xpos, Ypos, Zpos]) .
  57. ;
  58. ; KEYWORD PARAMETERS:
  59. ;       IMAGE:      If set, SEARCH3D returns a bi-level volume (3-D byte array)
  60. ;                   with the same dimensions as Array, containing the value
  61. ;                   (1) where the object is, and (0) where it isn't.
  62. ;       DIAGONAL:   Normally, cells are considered adjacent only when
  63. ;                   cubes surrounding the cells share a common face.
  64. ;                   If a non-zero value is passed to DIAGONAL then
  65. ;                   SEARCH3D will also locate cells meeting the search
  66. ;                   criteria whose surrounding cubes share a common
  67. ;                   edge or corner.  The default is no diagonal searching.
  68. ;                   Data type : int
  69. ;
  70. ;       DECREASE:   This keyword is now obsolete as are INCREASE and LPF_BAND.
  71. ;                   A better way to perform this operation is to pre-process
  72. ;                   the Array parameter before passing to SEARCH3D.
  73. ;       INCREASE:   See the DECREASE keyword.
  74. ;       LPF_BAND:   See the DECREASE keyword.
  75. ;
  76. ; OUTPUTS:
  77. ;       This function returns a list of the indices into the 3-D array
  78. ;       that are part of the located object or region. This list is
  79. ;       returned as a LONARR(n) where n is the number of cells found.
  80. ;
  81. ;       If the returned array of indices is called Region, and the
  82. ;       size of the 3-D volume of data is size_x by size_y by size_z,
  83. ;       then the actual X, Y, and Z indices can be obtained by using
  84. ;       the following algorithm :
  85. ;
  86. ;          index_z = Region / (size_x * size_y)
  87. ;          index_y = (Region - (index_z * size_x * size_y)) / size_x
  88. ;          index_x = (Region - (index_z * size_x * size_y)) - (index_y * size_x)
  89. ;
  90. ;       The object within the 3-D Array could then be subscripted as :
  91. ;
  92. ;          Array[Region]
  93. ;       OR
  94. ;          Array[index_x, index_y, index_z]
  95. ;
  96. ;       If the IMAGE keyword is set, however, SEARCH3D returns a bi-level
  97. ;       volume (3-D byte array) with the same dimensions as Array, containing
  98. ;       the value (1) where the object is, and (0) where it isn't.
  99. ;
  100. ; EXAMPLE:
  101. ;       Find all the indices corresponding to an object contained in a
  102. ;       3-D volume of data.
  103. ;
  104. ;       ; Create some data.
  105. ;          vol = RANDOMU(s, 40, 40, 40)
  106. ;          vol[3:13, 1:15, 17:33] = 1.3
  107. ;          vol[15:25, 5:25, 15:25] = 0.2
  108. ;          vol[5:30,17:38,7:28] = 1.3
  109. ;          vol[9:23, 16:27, 7:33] = 1.5
  110. ;
  111. ;       ; Search for an object starting at (6, 22, 16) whose data values
  112. ;       ; are between (1.2) and (1.4)..
  113. ;          Region = SEARCH3D(vol, 6, 22, 16, 1.2, 1.4, /DIAGONAL)
  114. ;
  115. ;       ; Scale the background cells into the range 0 to 127.
  116. ;          vol = BYTSCL(vol, TOP=127B)
  117. ;
  118. ;       ; Highlight the object region by setting it to 255.
  119. ;          vol[Region] = 255B
  120. ;
  121. ;       ; Set up a 3-D view.
  122. ;          Window, 0, Xsize=640, Ysize=512, Retain=2
  123. ;          Create_View, Xmax=39, Ymax=39, Zmax=39, ax=(-30), az=30, zoom=0.8
  124. ;
  125. ;       ; Display the volume with the highlighted object in it.
  126. ;          TVSCL, PROJECT_VOL(vol, 64, 64, 40, Depth_Q=0.4)
  127. ;
  128. ; MODIFICATION HISTORY:
  129. ;       Written by:     Daniel Carr. Thu Sep  3 17:36:04 MDT 1992
  130. ;       Modified:       Daniel Carr.
  131. ;                       Re-wrote to improve performance using "DILATE".
  132. ;                       Obsoleted keywords INCREASE, DECREASE, and LPF_BAND.
  133. ;                       Added IMAGE keyword.
  134. ;-
  135.  
  136. FUNCTION Search3d, array, xpos, ypos, zpos, min_val, max_val, $
  137.                    Diagonal=diagonal, Object=object, Decrease=decrease, $
  138.                    Increase=increase, Lpf_band=smooth_band
  139.  
  140. ON_ERROR, 2
  141.  
  142. IF (N_Elements(decrease) GT 0L) THEN $
  143.    Print, 'Search3D: Obsolete keyword "DECREASE" ignored.'
  144. IF (N_Elements(increase) GT 0L) THEN $
  145.    Print, 'Search3D: Obsolete keyword "INCREASE" ignored.'
  146. IF (N_Elements(smooth_band) GT 0L) THEN $
  147.    Print, 'Search3D: Obsolete keyword "LPF_BAND" ignored.'
  148.  
  149. IF (N_Elements(min_val) LE 0L) THEN min_val = MIN(array[xpos, ypos, zpos], Max=max_val)
  150. IF (N_Elements(max_val) LE 0L) THEN max_val = MAX(array[xpos, ypos, zpos])
  151.  
  152. s = Bytarr(3, 3, 3)
  153. IF (Keyword_Set(diagonal)) THEN s[*] = 1B $
  154. ELSE BEGIN
  155.    s[1, *, *] = 1B
  156.    s[*, 1, *] = 1B
  157.    s[*, *, 1] = 1B
  158. ENDELSE
  159.  
  160. size_array = size(array)
  161. xmax = size_array[1] - 1L
  162. ymax = size_array[2] - 1L
  163. zmax = size_array[3] - 1L
  164.  
  165. vol = Bytarr(size_array[1], size_array[2], size_array[3])
  166. vol[xpos, ypos, zpos] = 1B
  167.  
  168. ; Since "DILATE" does not handle the edges, it is necessary
  169. ; to propagate the edges manually.
  170.  
  171. vol[1L, *, *] = vol[1L, *, *] > vol[0L, *, *]
  172. vol[xmax-1L, *, *] = vol[xmax-1L, *, *] > vol[xmax, *, *]
  173. vol[*, 1L, *] = vol[*, 1L, *] > vol[*, 0L, *]
  174. vol[*, ymax-1L, *] = vol[*, ymax-1L, *] > vol[*, ymax, *]
  175. vol[0, 0, 1L] = vol[*, *, 1L] > vol[*, *, 0L]
  176. vol[0, 0, zmax-1L] = vol[*, *, zmax-1L] > vol[*, *, zmax]
  177. vol = Temporary(vol) and ((array GE min_val) and (array LE max_val))
  178. vol[xpos, ypos, zpos] = 1B
  179. last_found = 0L
  180. ne_obj = N_Elements(Where(vol))
  181. WHILE (ne_obj ne last_found) DO BEGIN
  182.    vol = Dilate(Temporary(vol), s)
  183.    vol = Temporary(vol) and ((array GE min_val) and (array LE max_val))
  184.    vol[xpos, ypos, zpos] = 1B
  185.    last_found = ne_obj
  186.    ne_obj = N_Elements(Where(vol))
  187. ENDWHILE
  188.  
  189. IF (Keyword_Set(object)) THEN RETURN, vol $
  190. ELSE RETURN, Where(vol)
  191.  
  192. END
  193.